package com.apes.scm.masterdata.party.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.repository.CustomRepository;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.scm.masterdata.area.model.Area;
import com.apes.scm.masterdata.area.repository.AreaRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.model.SupplierLogistic;
import com.apes.scm.masterdata.party.model.SupplierReachItem;
import com.apes.scm.masterdata.party.model.SupplierShipItem;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.party.repository.SupplierLogisticDao;
import com.apes.scm.masterdata.party.repository.SupplierLogisticRepository;
import com.apes.scm.masterdata.stock.model.PhyDepot;
import com.apes.scm.masterdata.stock.repository.PhyDepotRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 功能：供应商物流信息
 */
@Service("supplierLogisticService")
public class SupplierLogisticService extends DomainService {
    @Autowired
    SupplierLogisticRepository supplierLogisticRepository;
    @Autowired
    CorporateSerive corporateSerive;
    @Autowired
    AreaRepository areaRepository;
    @Autowired
    SupplierLogisticDao supplierLogisticDao;
    @Autowired
    SequenceService sequenceService;
    @Autowired
    PartyRoleRepository partyRoleRepository;
    @Autowired
    PhyDepotRepository phyDepotRepository;

    public SupplierLogistic create(SimpleRequest request) {
        SupplierLogistic supplierLogistic = request.getO(SupplierLogistic.class);
        checkSupplierLogistic(supplierLogistic);
        checkSupplierReachItem(supplierLogistic);
        resolveSupplierShipItem(supplierLogistic);
        return supplierLogisticRepository.save(supplierLogistic);
    }


    // 更新供应商信息
    public SupplierLogistic update(SimpleRequest request) {
        SupplierLogistic supplierLogistic = (SupplierLogistic) isVaild(request, supplierLogisticRepository);
        supplierLogistic = request.getO(SupplierLogistic.class);
        checkSupplierLogistic(supplierLogistic);
        checkSupplierReachItem(supplierLogistic);
        resolveSupplierShipItem(supplierLogistic);
        return supplierLogisticRepository.saveAndFlush(supplierLogistic);
    }

    public String delete(SimpleRequest request) {
        SupplierLogistic supplierLogistic = (SupplierLogistic) isVaild(request, supplierLogisticRepository);
        supplierLogisticRepository.delete(supplierLogistic);
        return "删除成功";
    }

    /***
     * 处理供应商发货地址
     */
    private void resolveSupplierShipItem(SupplierLogistic supplierLogistic) {

        supplierLogistic.getSupplierShipItems().stream().forEach(supplierShipItem -> {
            if( supplierShipItem.getCounty() == null ) return;
            Area regCounty = supplierShipItem.getCounty();// 注册地址.区县
            // 获取注册城市编码
            String regCityId = regCounty.getParent();
            // 查找注册城市
            Area regCity = areaRepository.findOne(regCityId);
            supplierShipItem.setCity(regCity); // 注册地址.城市
            // 设置注册城市
            String regProvinceId = regCity.getParent();
            Area regProvince = areaRepository.findOne(regProvinceId);
            supplierShipItem.setProvince(regProvince); //注册地址.省份
        });

    }

    /***
     * 处理供应商收货仓(限制存在多个相同的物理仓)
     */
    private void checkSupplierReachItem(SupplierLogistic supplierLogistic) {

        List<Map.Entry<String, List<SupplierReachItem>>>  entries = supplierLogistic.getSupplierReachItems().stream().collect(Collectors.groupingBy(supplierReachItem -> {
            return supplierReachItem.getPhyDepot().getId();
        })).entrySet().stream().filter(stringListEntry -> stringListEntry.getValue().size() > 1).collect(Collectors.toList());

        if(entries.size() > 0) throw new RuntimeException("当前供应商存在重复的收货仓");
    }

    /***
     * 处理供应商物流数据
     */
    private void checkSupplierLogistic(SupplierLogistic supplierLogistic) {

        SupplierLogistic uniqueItem =  supplierLogistic.getId() != null ?
                supplierLogisticRepository.findOne(JpaDsl.toCriteria(
                        "supplier.id", "EQ", supplierLogistic.getSupplier().getId(),
                        "id", "NE", supplierLogistic.getId()
                )).orElse(null) :
                supplierLogisticRepository.findOne(JpaDsl.toCriteria(
                        "supplier.id", "EQ", supplierLogistic.getSupplier().getId()
                )).orElse(null);

        if( uniqueItem != null ) throw new RuntimeException("已存在对当前供应商的物流信息定义，唯一码：" + uniqueItem.getId());

    }

    /***
     * 验证数据合法性
     */
    private Model isVaild(SimpleRequest request, CustomRepository repository){
        Model oldModel = (Model)  repository.findOne((String) request.get("id"));
        if (oldModel == null) throw new RuntimeException("订单【" + request.get("id") + "】在系统中不存在。");
        if (oldModel.getVersion() != (int) request.get("version")) throw new RuntimeException("记录已更新或已删除，请重新提交！");
        return oldModel;
    }


    /***
     * 导入数据专用
     */

    public void importData(SimpleRequest request) {
        importSupplierShipItem();
        importSupplierReachItem();
    }


    private void importSupplierShipItem(){
        JSONArray array = supplierLogisticDao.getSupplierShipItem();
        PartyRole company = partyRoleRepository.findOne("1001");

        array.forEach(json -> {
            JSONObject tempJson = (JSONObject) json;

            SupplierLogistic supplierLogistic = supplierLogisticRepository.findOne(
                    JpaDsl.toCriteriaByEq(
                            "supplier.id", tempJson.getString("SUPPLIER_ID").substring(2)
                    )
            ).orElse(null);

            if( supplierLogistic == null ) {
                PartyRole supplier = partyRoleRepository.findOne(tempJson.getString("SUPPLIER_ID").substring(2));
                if( supplier == null ) return; //throw new RuntimeException("在系统内未找到对应的供应商，供应商发货点供应商编码：" + tempJson.getString("SUPPLIER_ID"));

                supplierLogistic = new SupplierLogistic();
                supplierLogistic.setCompany(company); // 默认公司为1001
                supplierLogistic.setSupplier(supplier);
                supplierLogistic.setId(sequenceService.getId(SupplierLogistic.CONST_TABLE_NAME));
            }


            SupplierShipItem supplierShipItem = new SupplierShipItem();
            Area province = new Area();
            province.setId(tempJson.getString("PROVINCE_ID"));

            Area city = new Area();
            city.setId(tempJson.getString("CITY_ID"));

            Area county = new Area();
            county.setId(tempJson.getString("COUNTY_ID"));

            supplierShipItem.setId(sequenceService.getId(SupplierShipItem.CONST_TABLE_NAME));
            supplierShipItem.setSupplierLogistic(supplierLogistic);
            supplierShipItem.setProvince(province);
            supplierShipItem.setCity(city);
            supplierShipItem.setCounty(county);
            supplierShipItem.setContact(tempJson.getString("CONTACT"));
            supplierShipItem.setPhone(tempJson.getString("PHONE"));
            supplierShipItem.setAddress(tempJson.getString("ADDRESS"));
            supplierShipItem.setLatitude(tempJson.getDoubleValue("LATITUDE"));
            supplierShipItem.setLongitude(tempJson.getDoubleValue("LONGITUDE"));

            supplierLogistic.getSupplierShipItems().add(supplierShipItem);

            supplierLogisticRepository.saveAndFlush(supplierLogistic);
        });
    }


    private void importSupplierReachItem(){
        JSONArray array = supplierLogisticDao.getSupplierReachItem();
        PartyRole company = partyRoleRepository.findOne("1001");

        array.forEach(json -> {
            JSONObject tempJson = (JSONObject) json;

            SupplierLogistic supplierLogistic = supplierLogisticRepository.findOne(
                    JpaDsl.toCriteriaByEq(
                            "supplier.id", tempJson.getString("SUPPLIER_ID").substring(2)
                    )
            ).orElse(null);

            if( supplierLogistic == null ) {
                PartyRole supplier = partyRoleRepository.findOne(tempJson.getString("SUPPLIER_ID").substring(2));
                if( supplier == null ) return; //throw new RuntimeException("在系统内未找到对应的供应商，送达仓库供应商编码：" + tempJson.getString("SUPPLIER_ID"));

                supplierLogistic = new SupplierLogistic();
                supplierLogistic.setCompany(company); // 默认公司为1001
                supplierLogistic.setSupplier(supplier);
                supplierLogistic.setId(sequenceService.getId(SupplierLogistic.CONST_TABLE_NAME));
            }


            PhyDepot phyDepot = phyDepotRepository.findOne(tempJson.getString("PHY_DEPOT_ID"));
            if( phyDepot == null ) return; //throw new RuntimeException("在系统内未找到对应的物理仓库，物理仓库编码：" + tempJson.getString("PHY_DEPOT_ID"));


            boolean isExists = supplierLogistic.getSupplierReachItems().stream()
                    .filter(supplierReachItem -> supplierReachItem.getPhyDepot().getId().equals(tempJson.getString("PHY_DEPOT_ID")))
                    .findFirst().orElse(null) != null;

            if(isExists) return;

            SupplierReachItem supplierReachItem = new SupplierReachItem();
            supplierReachItem.setId(sequenceService.getId(SupplierReachItem.CONST_TABLE_NAME));
            supplierReachItem.setSupplierLogistic(supplierLogistic);
            supplierReachItem.setPhyDepot(phyDepot);


            supplierLogistic.getSupplierReachItems().add(supplierReachItem);

            supplierLogisticRepository.saveAndFlush(supplierLogistic);
        });
    }

}
